    var previewStrategy = {
    "name": "previewStrategy",
};


    //************
    // Main method
    //************

    function controllerLoop(time) {
        processMechanicalCondition(time);
        processFeulInventory(time);
        sendMessagesRoutine(time);
        processTutorial(time);
    }

    //Mechanical Condition parameters
    var currentMC = 0;
    var lastMalfunctionTime;

    var currentSpeed = 0;
    //var maintenanceTime = 0;
    var severeSpeedChangeTime;
    var severeSpeed;


    function processMechanicalCondition(time) { // todo: implement sub method
        forceRepairIfNeeded(time, currentMC);
        newMc = calcNewMechanicalCondition(time);
        if (newMc > currentMC) {
            // 1. write appropriate message.
            var content = { "from": currentMC, "to": newMc };
            addMessage(messages.mechanicalConditionChanged, content);

            // 2. update new mechanical condition, speed and shoot rate.
            lastMalfunctionTime = time;
            currentMC = newMc;
            setShootingBreakPercent(getNewScenario().getShootingBreakPercent(currentMC));
            setSpaceshipSpeed(getNewScenario().getSpeed(currentMC));

            if (currentMC == enumMC.SEVERE) {
                severeSpeedChangeTime = time;
            }

            changeMechanicalCondition(currentMC);

            calcMaintenanceTime(time);
            // Decreased points animation.
            //		demageCost = scenario.getDamageCost(currentMC);
            //		game.score.alive = true;
            //		game.score.init(game.ship.x - 50, game.ship.y - 50, demageCost, false);
            //		game.score.move();
            //		scoreEnd = currentTime + scoreTime;
            //		increaseScore(-demageCost);
        }
        calcSpeedAndShooutRate(time);
        processAlert(time);
    }

    function forceRepairIfNeeded(time, mc) {
        if (mc != enumMC.FIX) {
            var scenario = getNewScenario();
            var leftTime = scenario.gameLength - time;
            if (leftTime < scenario.getCostTable().getRepairTime(mc)) {
                mechanicalActionDone();
            }
        }
    }

    function calcNewMechanicalCondition(time) {
        var sampler = getNewScenario().mechanicalEventSampler;
        if (sampler.getNextTime() <= time) {
            if (currentMC < enumMC.SEVERE) {
                sampler.sampling(time);
                return currentMC + 1;
            }
        }
        return currentMC;
    }

    function setSpaceshipSpeed(speed1) {
        if (speed1 > 0) {
            currentSpeed = speed1;
        } else {
            if (currentSpeed > 0) {
                currentSpeed = 0;
                panelController.onFreezeDueToSeverMalfunction();
            }
        }
        game.ship.setSpeed(currentSpeed);
    }

    function calcSpeedAndShooutRate(time) {
        if (currentMC == enumMC.SEVERE) {
            if (time > severeSpeedChangeTime) {
                setSpaceshipSpeed(currentSpeed - 1);
                setShootingBreakPercent(game.ship.fireRate * 1.5);
                severeSpeedChangeTime = time + 2 * 1000;
            }
        }
    }

    function getCurrentMechanicalCondition() {
        return currentMC;
    }

    var alertBeforeDisplayed = false;
    var nextSnoozeDisplayed = false;
    var timeOfNextSnooze = 0;

    function processAlert(time) {
        var recomendedMaintenanceTime = getNewScenario().maintenanceAlert.getNextTime();
        if (alertStrategy.name == "alert3SecBefore" || alertStrategy.name == "alert3SecBeforeAndSnooze") {
            if (time + 3000 > recomendedMaintenanceTime) {
                if (alertBeforeDisplayed == false) {
                    var content = {
                        duration: 3000,
                        displayTime: 17000,
                        recomendedTime: 20000
                    }
                    addMessage(messages.alertBeforeDisplayed, content);
                    panelController.onMaintenanceAlert(3000);
                    // writeStatisticMsg(messages.alertBeforeDisplayed, "time=" + time);
                    alertBeforeDisplayed = true;
                }
            }
        }
    }

    function calcMaintenanceTime(time) {
        //20 seconds are recommended time to do maintenance by average player
        // when personalize will be supported then this method will be change. 
        getNewScenario().maintenanceAlert.setNextTime(time + 20 * 1000);
        alertBeforeDisplayed = false;
    }

    //called when player click on mechanical action button.
    function mechanicalActionDone() {
        onActionDone(enumAction.REPAIR);
        panelController.onMalfunctionRepair(currentMC);

        addPerformanceReportMessage();
        var content = {
            malfunctionTime: lastMalfunctionTime
        };
        addMessage(messages.repairAction, content);

        if (currentMC != enumMC.FIX) {
            var actionTime = getNewScenario().getCostTable().getRepairTime(currentMC);
            var actionCost = getNewScenario().getCostTable().getRepairCost(currentMC);

            //		game.score.alive = true;
            //		game.score.init(880, 580, actionCost, false);
            //		game.score.move();
            //		scoreEnd = currentTime + scoreTime;

            currentMC = enumMC.FIX;
            changeMechanicalCondition(enumMC.FIX);
            setShootingBreakPercent(getNewScenario().getShootingBreakPercent(currentMC));
            setSpaceshipSpeed(getNewScenario().getSpeed(currentMC));

            increaseScore(-actionCost);
            freezeSpaceship(actionTime);
        }
    }

    function maintenanceActionDone() {
        if (onActionDone(enumAction.MAINTENANCE) == false) {
            return;
        }
        maintenanceCost = getNewScenario().getCostTable().getCost(enumAction.MAINTENANCE);
        maintenanceDuration = getNewScenario().getCostTable().getTime(enumAction.MAINTENANCE);

        var sampleValue = getNewScenario().mechanicalEventSampler.sampling(currentTime);

        addPerformanceReportMessage();
        var content = {
            sampleValue: sampleValue
        };
        addMessage(messages.maintenaneAction, content);

        //game.score.alive = true;
        //game.score.init(880, 300, maintenanceCost, false);
        //game.score.move();
        //scoreEnd = currentTime + scoreTime;
        increaseScore(-maintenanceCost);

        panelController.onMaintenanceDone(maintenanceDuration);
        freezeSpaceship(maintenanceDuration);

        calcMaintenanceTime(currentTime + maintenanceDuration);
    }


    //*************************************
    //Fuel
    //*************************************

    var lastTimeFeulStationTime = 0;
    var stationsLocation = [];

    function processFeulInventory(time) {

        if (game.feulStatus <= 0) {
            //seen that total time of fill feul by spaceship is: (delay before time + flight time + fill time)
            callToFeulSpaceship(getNewScenario().costTable.getTime(enumAction.WAIT_TO_FUEL_SHIP));
        }
        calcNextStation(time);
        // warning strategy will be implemented later
    }

    function calcNextStation(time) {
        if (getNewScenario().fuelStationSampler.getNextTime() <= time) {

            // save time of fuel station creation.
            if (stationsLocation == undefined) {
                stationsLocation = [];
            }
            stationsLocation.push(time);

            // create new fuel station.
            var x = Math.floor(Math.random() * (Background.prototype.canvasWidth - 2 * imageRepository.feulship.width - 20) / imageRepository.feulship.width) * imageRepository.feulship.width + imageRepository.feulship.width + 10;
            makeAnewFeulStation(x);

            addMessage(messages.feulStationCreated, {});

            // determine the next time of fuel station creation.
            getNewScenario().fuelStationSampler.sampling(time);
        }
    }

    //Called when spaceship stop in fuel station.
    function feulFillDone() {
        onActionDone(enumAction.REFULING);
        addPerformanceReportMessage();
        addMessage(messages.feulFillDone, {});

        var scenario = getNewScenario();
        var costTable = scenario.getCostTable();
        var maxFuel = scenario.getMaxFeulInventory();

        var fuelCost = costTable.getRefuelingCost(maxFuel, game.feulStatus);
        increaseScore(-fuelCost);
        setFeulInventory(getNewScenario().getMaxFeulInventory());
        //increaseScore(-getNewScenario().costTable.getCost(enumAction.REFULING));


        var sec = getNewScenario().costTable.getTime(enumAction.REFULING);
        console.log("feulFillDone", sec);
        freezeSpaceship(sec);
        panelController.onRefueling(sec);
        return fuelCost;
    }

    function feulFillBySpaceship() {
        onActionDone(enumAction.REFULING_BY_FUEL_SHIP);
        addPerformanceReportMessage();
        addMessage(messages.feulFillBySpaceShipDone, {});

        setFeulInventory(getNewScenario().getMaxFeulInventory());
        increaseScore(-getNewScenario().costTable.getCost(enumAction.REFULING_BY_FUEL_SHIP));

        var sec = getNewScenario().costTable.getTime(enumAction.REFULING_BY_FUEL_SHIP);
        freezeSpaceship(sec);
        panelController.onRefueling(sec);
    }

    //*************
    //Performance
    //*************

    var shutdownTimes = [];
    var collistionTimes = [];
    var fireTimes = [];

    var numOfShootDown = 0;
    var numOfCollision = 0;
    var numOfFirePressed = 0;


    function onMeteorShootDown() {
        numOfShootDown++;
        shutdownTimes.push(currentTime);
    }

    function onMeteorCollision() {
        collistionTimes.push(currentTime);
        numOfCollision++;
    }

    function onFirePressed() {
        numOfFirePressed++;
        fireTimes.push(currentTime);
    }



    //**********************
    // initial & finish game
    //**********************

    function initParms() {
        msgIndex = 0;

        if (game) {
            game.playerScore = 0;
        }
        //set parameters
        if (currentMC != enumMC.FIX) {
            changeMechanicalCondition(enumMC.FIX);
        }

        var scenario = getNewScenario();
        scenario.mechanicalEventSampler.sampling(0);
        scenario.fuelStationSampler.sampling(0);

        currentSpeed = scenario.getSpeed(enumMC.FIX);
        currentMC = enumMC.FIX;

        calcMaintenanceTime(0);

        numOfShootDown = 0;
        numOfCollision = 0;

        lastMessageSendingTime = messageSendingTimeInterval;
        msgSeqNumber = 0;

        addMessage(messages.gameStart, {});
    }

    function onGameFinish() {
        sendRestMessages();
    }

//****************************************************************************************************************************************
//****************************************************************************************************************************************
//All methods that embedded in control loop and their implementation should be different in controllerPreview.js should be located under this row.
//****************************************************************************************************************************************
//****************************************************************************************************************************************


//********
//Messages
//********

var msgIndex = 0;

var msgSeqNumber;
var messagesList = [];

var messageSendingTimeInterval = 30 * 1000;
var lastMessageSendingTime = 0;


function sendMessagesRoutine(time){}

function getHeader(msgTitle){}

function addMessage(msgTitle, content){}

function popMessageList(){}

function addPerformanceReportMessage(){
	return {};
}

function sendMessages(messageList){
	//console.log(JSON.stringify(messageList));
}

function writeStatisticMsg(msgTitle, content) {}


var showUserDialoge = true;
function writeMsgForUser(title, msg) {}

//****************
//preview methods that embedded in control loop
//****************

function onActionDone(action){
	if (action == enumAction.REPAIR && trial_status == trial_repair){
			trial_repair_done = 1;	
			return true;
	}
	if (action == enumAction.MAINTENANCE && trial_status == trial_maintenance){
			trial_maintenance_done = 1;
			return true;
	}
	if (action == enumAction.REFULING){
		trial_fillFeul_done = 1;
		return true;
	}
	if (action == enumAction.REFULING_BY_FUEL_SHIP){
		trial_fillFeulBySpaceShip_done = 1;
		return true;
	}
	
	return false;
}

function isPreviewController() {
  return true;
}

//******************* trial parameters & functions ******************************

var trial_status = 0;
var trial_meteorShut = 1;
var trial_meteorShut_start = 0;
var trial_meteorCollision = 2;
var trial_meteorCollision_start = 0;
var trial_fillFeul = 3;
var trial_fillFeul_done = 0;
var trial_fillFeulBySpaceShip = 4;
var trial_fillFeulBySpaceShip_done = 0;
var trial_maintenance = 5;
var trial_maintenance_done = 0;
var trial_repair = 6;
var trial_repair_done = 0;
var trial_success = 7;
var trial_success_done = 0;

var currentTrialSession_endTime;

function processTutorial(time) {
	if (freezeShip){
		return;
	}
	if (trial_status == undefined || trial_status == 0){
		initTrial();
		trial_status = trial_meteorShut;
		return;
	}
	
	if (trial_status == trial_success){
		return;
	}
	
	if (time >= 120000 || time >= getNewScenario().gameLength) { // go to real game after 120 seconds
		endTrial(time);
	}
	
	// trial_meteorShut
	if (trial_status == trial_meteorShut){
		if (trial_meteorShut_start == undefined || trial_meteorShut_start == 0){
			startMeteorsShut(time);
			trial_meteorShut_start = 1;
		} else{
			if (currentTrialSession_endTime <= time){
				trial_status = trial_meteorCollision;
			}
		}
		return;
	}

	// 1) trial_meteorCollision
	if (trial_status == trial_meteorCollision){
		if (trial_meteorCollision_start == undefined || trial_meteorCollision_start == 0){
			startMeteorCollision(time);
			trial_meteorCollision_start = 1;
		} else {
			if (currentTrialSession_endTime <= time){
				trial_status = trial_fillFeul;
				startTrial_fillFeul(time);
			}
		}
		return;
	}

	// 2) trial_fillFeul
	if (trial_status == trial_fillFeul){
		if (trial_fillFeul_done == 1){
			trial_status = trial_fillFeulBySpaceShip;
			startTrial_fillFeulBySpaceShip(time);
		}
		return;
	}

	// 3) trial_fillFeulBySpaceShip
	if (trial_status == trial_fillFeulBySpaceShip){
		if (trial_fillFeulBySpaceShip_done == 1){
			trial_status = trial_maintenance;
			startTrial_maintenance(time);
		}
		return;
	}

	// 4) trial_maintenance
	if (trial_status == trial_maintenance){
		if (trial_maintenance_done == 1){
			trial_status = trial_repair;
			startTrial_repair(time);
		}
		return;
	}
	if (trial_status == trial_repair){
		if (trial_repair_done == 1){
			endTrial(time);
		}
	}
}

function initTrial(){
	trial_meteorShut = 1;
	trial_meteorCollision = 2;
	trial_fillFeul = 3;
	trial_fillFeulBySpaceShip = 4;
	trial_maintenance = 5;
	trial_repair = 6;
	trial_success = 7;
	
	getNewScenario().mechanicalEventSampler.setNextTime(999 * 1000);
	getNewScenario().fuelStationSampler.setNextTime(999 * 1000);
	writeTutorialMsg("Trial Game","Press Ok to start the game");
}

function startMeteorsShut(time){
	writeTutorialMsg("Shoot down Meteors", "Shoot down meteors by pressing the space-bar and control the ship with the arrow keys.");
	if (time == undefined){
		time = 0;
	}
	currentTrialSession_endTime = time + (10 * 1000);
}


function startMeteorCollision(time){
	writeTutorialMsg("Collision with Meteors", "Try to collide into a meteor in the following 10 seconds. See how you can lose points($) then.");
	currentTrialSession_endTime = time + (10 * 1000);
}

function startTrial_fillFeul(time) {
	trial_fillFeul_done = 0;
	getNewScenario().fuelStationSampler.setNextTime(time + (5 * 1000));
	writeTutorialMsg("Fill the fuel tank","Notice how the fuel percentage decreases in the fuel chart on the bottom-right side of the screen. You can fuel your spaceship by reaching a fuel station that will be shown in a few seconds.");
}

function startTrial_fillFeulBySpaceShip(time) {
	trial_fillFeulBySpaceShip_done = 0;
	getNewScenario().fuelStationSampler.setNextTime(time + (999*1000));
	setFeulInventory(10000);
	writeTutorialMsg("Empty Fuel Tank","When the fuel tank is empty (look at the fuel gauge on bottom-right of the screen), the spaceship will stop. The ship will be able to navigate once a fuel spaceship arrives at your ship and refills its tank. Make sure you get enough fuel in the fuel stations while flying.");
}

function startTrial_maintenance(time) {
	trial_maintenance_done = 0;
	setFeulInventory(1000000);
	writeTutorialMsg("Maintenance Actions", "To reduce the probability of malfunctions, you should perform maintenance every 20 seconds." +
			"<br><b>Maintenance duration: </b> 2 seconds" +
			"<br><b>Cost: </b>20 points($)" +
	"<br> Press the maintenance button on the top-right side of the screen to practice this action.");
}

function startTrial_repair(time) {
	trial_repair_done = 0;
	getNewScenario().mechanicalEventSampler.setNextTime(time + (3*1000));
	writeTutorialMsg("Repair Actions", "Look at the icons and their colors on the center of the right side screen. Wait until a malfunction appears and then press the repair button.");
}

function endTrial(time) { // reset scenario parameters
	trial_status = trial_success;
	//currentCycle = [1000 + time, 10 + time, 15 + time, 20 + time];
	$("#dialog-message").html("The training game has been finished. The real 3 games will start now and it will take 2 minutes for first game and 4 minutes for others.");
	$("#dialog-message").dialog({
		modal : false,
		title : "End training",
		width: 400,
		position: { my: "center", at: "center", of: $("#main") },
		buttons :[ {
			text: "Ok",
			click: function () {
				$(this).dialog("close");
				window.location =  window.url;
			}
		}]
	});
}

function writeTutorialMsg(title, msg) {
	$("#dialog-message").html(msg);
	$("#dialog-message").dialog({
		modal : false,
		title : title,
		width: 400,
		position: { my: "center", at: "center", of: $("#main") },
		buttons :[ {
			text: "Ok",
			click: function () {
				$(this).dialog("close");
				pauseGame = false;
				timer.Timer.play();
				animate();


			}
		}]
	});
	pauseGame = true;
	timer.Timer.pause();
}




